package com.example.sources.beans.factory;

import com.example.sources.annotation.*;
import com.example.dao.UserDao;
import com.example.sources.jdbc.proxy.DaoInvocationHandlerImpl;
import com.example.sources.jdbc.proxy.DynamicProxy;
import com.example.sources.util.ClassFileUtil;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 工厂类  用于初始化bean
 */
public class BeanFactory extends  Factory{
    private Map<String,Object> beansMap = new HashMap<>();

    @Override
    public void createFactory() {
        try {
            List<Class> classList = new ClassFileUtil().getClassList("");
            for (Class<?> c:classList){

                Annotation[] annotations  = c.getAnnotations();
                if (annotations.length != 0){
                    if (c.getAnnotation(MyRepository.class)!=null){  //TODO 改进它 做到耦合性低
                        setDaoProxy(c);
                        System.out.println(c.getName());
                    }else {
                    for (Annotation annotation :annotations){
                            if (annotation.annotationType().getAnnotation(MyComponent.class)!=null){
                                setBeanMap(c.getName());

                            }
                    }
                    }
                }
            }
        injectObject();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    }



    @Override
    public Object getBean(String bean) {
        return beansMap.get(bean);
    }

    @Override
    public void setBean(String beanName, Object o) {
        beansMap.put(beanName,o);
    }

    private void setDaoProxy(Class<?> c) {
        UserDao o = DynamicProxy.newProxyInstance(DaoInvocationHandlerImpl.class.getClassLoader(),new Class[]{c},new DaoInvocationHandlerImpl());
        beansMap.put(c.getName().split("\\.")[c.getName().split("\\.").length-1],o);
    }

    private void setBeanMap(String beanName) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
            Class c = Class.forName(beanName);
            Object o = c.newInstance();
            beansMap.put(beanName.split("\\.")[beanName.split("\\.").length-1],o);  //TODO 储存的key值修改一下,最好是类全名
    }

//注入Map中类申明的域的值
    private void injectObject() throws IllegalAccessException {

        for (Object o : beansMap.values()){
            Field[] fields = o.getClass().getDeclaredFields();
            for (Field field:fields){
                MyResources resources = field.getAnnotation(MyResources.class);
                if (resources!=null){
                    field.setAccessible(true);
                    field.set(o,beansMap.get(resources.name()));
                }
            }
        }
    }

    public void injectObject(String beanname) throws IllegalAccessException {
        Object o = beansMap.get(beanname);
        if (o != null){
            Field[] fields = o.getClass().getDeclaredFields();
            for (Field field:fields){
                MyResources resources = field.getAnnotation(MyResources.class);
                if (resources!=null){
                    field.setAccessible(true);
                    field.set(o,beansMap.get(resources.name()));
                }
            }
        }else {
            System.out.println(beanname+"不存在不能注入");
        }
    }
    public Map<String,Object> getBeansMap(){
        return beansMap;
    }
}
